package com.lincolnXmypcqq.robot;

import com.lincoln.framework.bean.NettyContext;
import com.lincolnXmypcqq.cmds.framework.RobotCmd;
import com.lincolnXmypcqq.cmds.framework.RobotCmdExecuteResult;
import com.lincolnXmypcqq.cmds.framework.RobotCmdFactory;
import com.lincolnXmypcqq.netty.DealChat;
import com.lincolnXmypcqq.robot.framework.RobotDealContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

/**
 * @param
 * @author ziyao.peng01@ucarinc.com
 * @description 消息处理流程
 * @date 2018/11/29 11:15
 * @return
 */
public class RobotDeal extends Thread {
    private static Logger logger = LoggerFactory.getLogger(RobotDeal.class);


    /**
     * 执行状态
     * 状态枚举{@link com.lincolnXmypcqq.robot.RobotDealState}
     */
    private int state;

    /**
     * @description 实例化时传递参数
     */
    private Map<String, Object> params;

    public RobotDeal(Map<String, Object> params) {
        this.params = params;
        this.state = RobotDealState.WAIT.getValue();
    }


    @Override
    public void run() {
        //将自身放入当前上下文
        RobotDealContext.init(params);
        RobotDealContext.setRobotDeal(this);

        if (StringUtils.isEmpty(RobotDealContext.getRobotQQ()) || RobotDealContext.getMsgType() == null ||
                RobotDealContext.getSubMsgType() == null || StringUtils.isEmpty(RobotDealContext.getFrom()) ||
                StringUtils.isEmpty(RobotDealContext.getFromQQ()) || StringUtils.isEmpty(RobotDealContext.getToQQ()) ||
                StringUtils.isEmpty(RobotDealContext.getContent())) {
            return;
        }
        this.state = RobotDealState.EXECUTING.getValue();
        pre();
        execute();
        after();
    }

    /**
     * @param
     * @return void
     * @description 第一阶段命令执行, 一些前置操作(一般不分消息类型, 或者对某一特定类型做特殊处理)
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/29 11:09
     */
    public void pre() {
        if (this.state == RobotDealState.FAIL.getValue()) {
            return;
        }
        List<RobotCmd> robotCmds = RobotCmdFactory.findRobotCmdMsg();
        execute(robotCmds);
    }

    /**
     * @param
     * @return void
     * @description 第二阶段对不同类型的任务进行处理
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/29 14:58
     */
    public void execute() {
        if (this.state == RobotDealState.FAIL.getValue()) {
            return;
        }
        List<RobotCmd> robotCmds = RobotCmdFactory.findRobotCmd();
        execute(robotCmds);
    }

    /**
     * @param
     * @return void
     * @description 最后执行阶段, 做一些数据回收
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/29 14:59
     */
    public void after() {
        this.state = RobotDealState.DONE.getValue();
    }

    /**
     * @param robotCmds
     * @return void
     * @description 批量执行单体任务
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/29 11:29
     */
    public void execute(List<RobotCmd> robotCmds) {
        if (null != robotCmds && robotCmds.size() > 0) {
            RobotDealContext.addRobotCmds(robotCmds);
            for (RobotCmd robotCmd : robotCmds) {
                try {
                    execute(robotCmd);
                } catch (Exception e) {
                    break;
                }
            }
        }
    }

    /**
     * @param robotCmd
     * @return void
     * @description 执行单体任务
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/29 11:29
     */
    public void execute(RobotCmd robotCmd) throws Exception {
        RobotCmdExecuteResult robotCmdExecuteResult = new RobotCmdExecuteResult();
        robotCmdExecuteResult.setRobotCmd(robotCmd);
        try {
            boolean result = (boolean) robotCmd.getDone().invoke(robotCmd.getDone().getDeclaringClass().newInstance());
            robotCmdExecuteResult.setResult(result);
        } catch (Exception e) {
            robotCmdExecuteResult.setResult(false);
            robotCmdExecuteResult.setE(e);
        }
        RobotDealContext.addRobotCmdExecuteResult(robotCmdExecuteResult);
        if (!robotCmdExecuteResult.getResult()) {
            this.state = RobotDealState.FAIL.getValue();
            throw new Exception();
        }
    }

    /**
     * @param robotQQ, msgType, subMsgType, to, toQQ, content
     * @return void
     * @description 发送消息
     * @author ziyao.peng01@ucarinc.com
     * @date 2018/11/27 15:10
     */
    public static void sendMsg(String robotQQ, int msgType, int subMsgType, String to, String toQQ, String content) {
        if (NettyContext.getClient(robotQQ) != null) {
            DealChat dealChat = new DealChat();
            dealChat.send((robotQQ + "|" + String.valueOf(msgType) + "|" + String.valueOf(subMsgType) + "|" + to + "|" + toQQ + "|" + content).getBytes());
        }
    }
}
